package com.hengxinguotong.zhihuichengjian.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期格式化及转换工具
 * "yyyy-MM-dd HH:mm:ss"
 */
public class DateUtil {

    public static final long AHourTimeLong = 60*60;//一个小时的秒数
    public static final long ADayTimeLong = 24*60*60;//一天的秒数
    /**
     * 时间格式样式
     */
    public static String DATE_FORMAT_1 = "yyyy-MM-dd hh:mm:ss";
    public static String DATE_FORMAT_2 = "yyyy-MM-dd";

    public int getDay(String year,String month){
        int mon = Integer.parseInt(month);
        int yea = Integer.parseInt(year);
        int day = 0 ;
        switch (mon){
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                day = 31;
                break;
            case 2:
                if(isLeapYear(yea)){
                    day = 29;
                } else {
                    day = 28;
                }
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                day = 30;
                break;
        }
        return day;
    }


    /**
     * 是否是闰年
     * 闰年的条件是：
     ① 能被4整除，但不能被100整除；
     ② 能被100整除，又能被400整除。
     * @param year
     * @return
     */
    public boolean isLeapYear(int year){
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    }


    /**
     * 时间戳---->字符串格式日期
     * @param time   long类型的时间值 ms
     * @param format  格式样式
     * @return
     */
    public static String formatTimeStamp(long time,String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(time);
    }

    /**
     * 字符串格式日期---->日期
     * @param dateStr
     * @return
     */
    public static Date formatStrToDate(String dateStr,String format){
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        Date result=null;
        try {
            result = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 字符串格式日期---->时间戳
     * @param dateStr
     * @return 毫秒值ms
     */
    public static long formatStrToTimeStamp(String dateStr,String format){
        Date date = formatStrToDate(dateStr, format);
        return date.getTime();
    }

    /**
     * 获取指定日期所在周的第一天
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }


    /**
     * 获取指定日期所在周的最后一天
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }


    /**
     * 获取指定日期所在月的第一天
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 获取指定日期所在月的最后一天
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH,c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    /**
     * 获取指定日期所在年第一天日期
     *
     */
    public static Date getFirstDayOfYear(Date data){
        Calendar c = Calendar.getInstance();
        c.setTime(data);
        c.set(Calendar.DAY_OF_YEAR,1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 获取指定日期所在年最后一天日期
     *
     */
    public static Date getLastDayOfYear(Date data){
        Calendar c = Calendar.getInstance();
        c.setTime(data);
        c.set(Calendar.DAY_OF_YEAR,c.getActualMaximum(Calendar.DAY_OF_YEAR));
        return c.getTime();
    }


    /**
     * 在指定的时间加特定的天数
     */
    public static String addDays(String dateStr,String format,int days){
        Date date = formatStrToDate(dateStr, format);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, days);//加减天数

        return formatTimeStamp(c.getTimeInMillis(),format);
    }


    /**
     * 时间格式转换
     * @param dateStr 时间字符串
     * @param format1 当前格式
     * @param format2 目标格式
     * @return
     */
    public static String convertFormat(String dateStr,String format1,String format2){
        Date date = formatStrToDate(dateStr, format1);
        return formatTimeStamp(date.getTime(),format2);
    }

    /**
     * 获得指定时间加减参数后的日期(不计算则输入0)
     * @param date 指定日期
     * @param year 年数，可正可负
     * @param month 月数，可正可负
     * @param day 天数，可正可负
     * @param hour 小时数，可正可负
     * @param minute 分钟数，可正可负
     * @param second 秒数，可正可负
     * @param millisecond 毫秒数，可正可负
     * @return 计算后的日期
     */
    public static Date addDate(Date date,int year,int month,int day,int hour,int minute,int second,int millisecond){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, year);//加减年数
        c.add(Calendar.MONTH, month);//加减月数
        c.add(Calendar.DATE, day);//加减天数
        c.add(Calendar.HOUR,hour);//加减小时数
        c.add(Calendar.MINUTE, minute);//加减分钟数
        c.add(Calendar.SECOND, second);//加减秒
        c.add(Calendar.MILLISECOND, millisecond);//加减毫秒数

        return c.getTime();
    }

    /**
     * 根据提供的年月日获取该月份的第一天

     * @param year
     * @param monthOfYear
     * @return
     */
    public static Date getSupportBeginDayofMonth(int year, int monthOfYear) {
        Calendar cal = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, monthOfYear -1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        Date firstDate = cal.getTime();
        return firstDate;
    }

    /**
     * 根据提供的年月获取该月份的最后一天
     * @param year
     * @param monthOfYear
     * @return
     */
    public static Date getSupportEndDayofMonth(int year, int monthOfYear) {
        Calendar cal = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, monthOfYear - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);

        Date lastDate = cal.getTime();
        return lastDate;
    }

    /**
     * 根据年月日返回时间戳，当前日期的0点0分0秒
     *
     * @param ymd
     * @return 返回单位为秒
     */
    public static long initTimeStamp(int[] ymd) {
        long timeStamp = 0;
        Calendar cal = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal.set(Calendar.YEAR, ymd[0]);
        cal.set(Calendar.MONTH, ymd[1]-1);
        cal.set(Calendar.DAY_OF_MONTH, ymd[2]);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date date = cal.getTime();
        timeStamp = date.getTime()/1000;
        return timeStamp;
    }


    /**
     * 将时间初始化时间戳
     * @param ymd 年月日
     * @param hm  时分
     * @return   单位为秒的时间戳
     */
    public static long initTimeStamp(int[] ymd,int[] hm){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,ymd[0]);
        cal.set(Calendar.MONTH,ymd[1]-1);
        cal.set(Calendar.DAY_OF_MONTH,ymd[2]);
        cal.set(Calendar.HOUR_OF_DAY,hm[0]);
        cal.set(Calendar.MINUTE,hm[1]);
        cal.set(Calendar.SECOND,0);

        return cal.getTime().getTime()/1000;
    }

    /**
     * 根据时间戳，对应当天0点0分0秒的时间
     * @param timestamp 单位为秒
     * @return 返回单位也为秒
     */
    public static long reSetDateTime(long timestamp){
        Date date = new Date(timestamp * 1000);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);

        return date.getTime()/1000;
    }

    /**
     * 两个日期相隔的天数
     * @param time1
     * @param time2
     * @param format
     * @return
     */
    public static int getDistanceDay(String time1, String time2,String format) {
        long l1 = formatStrToTimeStamp(time1, format);
        long l2 = formatStrToTimeStamp(time2, format);

        int day = 0;
        long diff;
        if (l1 < l2) {
            diff = l2 - l1;
        } else {
            diff = l1 - l2;
        }
        day = (int) (diff / (24 * 60 * 60 * 1000));
        return day;
    }


    /**
     *  *计算time2减去time1的差值 差值只设置 几个小时 或 几分钟
     * 根据差值返回多长之间前或多长时间后
     * @param time1 单位为毫秒
     * @param time2 单位为毫秒
     * @return
     */
    public static String getDistanceTime(long time1, long time2) {
//        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        long diff;

        if (time1 < time2) {
            diff = time2 - time1;
        } else {
            diff = time1 - time2;
        }
//        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000));
        min = ((diff / (60 * 1000)) - hour * 60);
        sec = (diff / 1000  - hour * 60 * 60 - min * 60);
        if (hour != 0)
            return hour + "小时" + min + "分钟" + sec + "秒";
        if (min != 0)
            return min + "分钟" + sec + "秒";
        if (sec != 0)
            return sec + "秒";
        return "0秒";
    }


    /**
     *  *计算time2减去time1的差值 差值只设置 几个小时 或 几分钟
     * 根据差值返回多长之间前或多长时间后
     * @param diff 单位为毫秒
     * @return
     */
    public static String getDistanceTime(long diff) {
//        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;

        if (diff<0) {
            diff = -diff;
        }

//        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000));
        min = ((diff / (60 * 1000)) - hour * 60);
        sec = (diff / 1000 - hour * 60 * 60 - min * 60);
//        if (day != 0)
//            return day + "天" + hour + "小时" + min + "分钟" + sec + "秒";
        if (hour != 0)
            return hour + "小时" + min + "分钟" + sec + "秒";
        if (min != 0)
            return min + "分钟" + sec + "秒";
        if (sec != 0)
            return sec + "秒";
        return "0秒";
    }

    /**
     * 格式化时间，将minute转换为 xx小时xx分钟
     * @param minute
     * @return
     */
    public static String formatTimeOfMinute(long minute) {
//        long day = 0;
        long hour = 0;
        long min = 0;

        if (minute<0) {
            minute = -minute;
        }

//        day = (minute / (24 * 60 ));
        hour = minute / 60 ;
        min = (minute - hour * 60);
//        if (day != 0)
//            return day + "天" + hour + "小时" + min + "分钟" ;
        if (hour != 0)
            return hour + "小时" + min + "分钟";
        if (min != 0)
            return min + "分钟";

        return "0分钟";
    }

}
